﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 战棋模拟器
{
    class Pool
    {
        //数据结构部分
        public bool direction;//可以认为0为下方，1为上方
        public Board board;
        public int current;//指当前攻击的位置
        //每当将要进行攻击的时候，把攻击的位置++，这是为了在亡语召唤或者受伤召唤的时候可以正确指向。
        //每当随从死亡的时候，如果死亡位置在攻击的位置或之前，攻击的位置--，这是为了得到正确的序列，不会跳怪。
        //每当成功召唤的时候，如果召唤位置在攻击的位置或之前，应当让攻击的位置++，理由同上
        //在攻击时检测当攻击的位置超过6或者是null时，置为0，并且必须检测是否所有随从都是0攻
        //如果检测到所有随从都是0攻，应当将current置为-1，这样在蛋被打破后能够正常运算。
        public Minion[] places;
        public int minionCount;
        public Pool next;

        public List<Minion> DeathList;//坟场

        //构造器部分
        public Pool(params Minion[] minions)//要求从左至右写入随从
        {
            places = new Minion[7];
            DeathList = new List<Minion>();
            current = -1;
            minionCount = 0;
            for(int i = 0;i < minions.Length; i++)
            {
                minions[i].pool = this;
                places[i] = minions[i];
                places[i].Place = i;
                minionCount++;
            }
        }



        //判断战斗力：有怪有战斗力(1)，有怪没战斗力(0)，没怪(-1)
        public int Check()
        {
            int r = -1;
            for (int i = 0; i < 7; i++)
            {
                if (places[i] == null)
                    break;
                if (places[i].Attack == 0)
                {
                    r = 0;
                    continue;
                }
                if (places[i].Attack > 0)
                    return 1;
            }
            return r;
        }


        //按顺位添加一个随从
        public bool AddMinion(Minion m)
        {
            int i = minionCount;
            if (i == 7)
                return false;
            places[i] = m;
            m.Place = i;
            minionCount++;
            m.pool = this;
            return true;
        }


        //在指定位置插入一个随从 从0-6
        public bool AddMinion(int place, Minion m)
        {
            if (minionCount == 7)
                return false;
            if (place > 0)
                while (place > 0 && places[place - 1] == null)
                    place--;
            //place指向第一个空位的下标
            for (int i = 6; i > place; i--)
                if (places[i - 1] != null)
                {
                    places[i - 1].Place++;
                    places[i] = places[i - 1];
                }
            places[place] = m;
            m.Place = place;
            minionCount++;
            m.pool = this;
            if (board.Debug)
                Console.WriteLine("在{0}第{2}个位置添加了一个{1}随从", direction ? "上方" : "下方", m.Name, place);
            return true;
        }


        //在此pool中寻找对手,先在有嘲讽的随从中考察，没有找到则在所有随从中考察，返回随从的引用
        public Minion GetOpponent(params int[] IsMomHunting)
        {
            if (IsMomHunting.Length == 0)
            {
                bool taunt = false;
                int available = 0;//有多少个可以挨揍
                List<int> attackeearray = new List<int>();
                for (int i = 0; i < 7; i++)
                {
                    if (places[i] == null)
                        break;
                    if (places[i].Skills[2])
                    {
                        taunt = true;
                        available++;
                        attackeearray.Add(i);
                    }
                }
                if (!taunt)
                {
                    for (int i = 0; i < 7; i++)
                    {
                        if (places[i] == null)
                            break;
                        attackeearray.Add(i);
                        available++;
                    }
                }
                if (available == 0)
                    return null;
                byte[] buffer = Guid.NewGuid().ToByteArray();
                int iSeed = BitConverter.ToInt32(buffer, 0);
                Random ran = new Random(iSeed);
                int RandKey = ran.Next(0, available);
                if (board.Debug)
                    Console.WriteLine("选择了{0}第{1}个随从作为对手", direction ? "上方" : "下方", attackeearray[RandKey]);
                return places[attackeearray[RandKey]];
            }
            else if (IsMomHunting[0] == 1)
            {
                List<Minion> LeastAttck = new List<Minion>();
                int min = places[0].Attack;
                foreach (Minion m in places)
                {
                    if (m == null)
                        break;
                    if (m.Attack < min)
                        min = m.Attack;
                }
                foreach (Minion m in places)
                {
                    if (m == null)
                        break;
                    if (m.Attack == min)
                        LeastAttck.Add(m);
                }
                byte[] buffer = Guid.NewGuid().ToByteArray();
                int iSeed = BitConverter.ToInt32(buffer, 0);
                Random ran = new Random(iSeed);
                int RandKey = ran.Next(0, LeastAttck.Count);
                if (board.Debug)
                    Console.WriteLine("选择了{0}第{1}个随从作为对手", direction ? "上方" : "下方", LeastAttck[RandKey].Place);
                return LeastAttck[RandKey];
            }
            else return null;//目前框架下无定义。
        }


        public int TrueCount()
        {
            if (minionCount == 0)
                return 0;
            int r = minionCount;
            foreach(Minion m in places)
            {
                if (m == null)
                    break;
                if (board.deadQ.Contains(m))
                    r--;
            }
            return r;
        }


        //召唤随从，考虑到卡德加可以给对面生比斯巨兽的仔
        public bool Spawn(Pool p, int place, Minion m)
        {
            m.Place = place;
            m.pool = p;
            bool r = p.AddMinion(place, m);
            if (r && place <= p.current)
                p.current++;
            if (r)
            {//这里要实现正确的迭代，否则用指针做指标或者用ｆｏｒｅａｃｈ　ｉｎ　ｐｌａｃｅｓ都会由于生成新的随从而造成问题
                m.Initialize();
                List<Minion> Other = new List<Minion>(),Ka = new List<Minion>();
                foreach(Minion n in p.places)
                {
                    if (n == null)
                        break;
                    if (n != m && n.Name != "卡德加" && n.Name != "卡德加_金色")
                        Other.Add(n);
                    if (n != m && (n.Name == "卡德加" || n.Name == "卡德加_金色"))
                        Ka.Add(n);
                }
                foreach (Minion n in Other)
                    n.OnSpawn(m);
                foreach (Minion n in Ka)
                    n.OnSpawn(m);
                Other = new List<Minion>();
                Ka = new List<Minion>();
                foreach (Minion n in p.next.places)
                {
                    if (n == null)
                        break;
                    if (n.Name != "卡德加" && n.Name != "卡德加_金色")
                        Other.Add(n);
                    if (n.Name == "卡德加" || n.Name == "卡德加_金色")
                        Ka.Add(n);
                }
                foreach (Minion n in Other)
                    n.OnEnemySpawn(m);
                foreach (Minion n in Ka)
                    n.OnEnemySpawn(m);
            }
            return r;
        }


        //正确让current指向下一个有意义的单位
        public void CurrentAddOne()
        {
            current++; 
            if (current >= minionCount)
            {
                current = 0;
                
            }
            while (places[current].Attack == 0)
            {
                current++;
                
                if (current >= minionCount)
                {
                    current = 0;
                    
                }
            }
        }


        //初始化
        public void Initialize()
        {
            foreach (Minion m in places)
                if (m != null)
                    m.Initialize();
        }



        public void OnDragonKill()
        {
            foreach (Minion m in places)
            {
                if (m == null)
                    break;
                if(m.Name == "蜡烛骑士托瓦格尔"||m.Name=="蜡烛骑士托瓦格尔_金色")
                {
                    m.Attack += m.buff;
                    m.Health += m.buff;
                    if(board.Debug)
                    {
                        Console.WriteLine("龙造成击杀,{3}方第{4}位{0}获得+{1}/+{2}",
                            m.Name,
                            m.buff,
                            m.buff,
                            m.pool.direction?"上":"下",
                            m.Place);
                    }
                }
            }
        }



        public Minion RandomMinion()
        {
            byte[] buffer = Guid.NewGuid().ToByteArray();
            int iSeed = BitConverter.ToInt32(buffer, 0);
            Random ran = new Random(iSeed);
            if (minionCount == 0)
                throw new Exception("随从池为空拒绝挑选随机随从");
            int c = TrueCount();
            int Randkey = ran.Next(0, c);
            int i = -1;
            while(c>0)
            {
                i++;
                if (!board.deadQ.Contains(places[i]))
                    c--;
            }
            return places[i];
        }


        public Pool Copy()
        {
            Pool r = new Pool();
            for(int i = 0;i<7;i++)
            {
                if (places[i] == null)
                    break;
                r.AddMinion(places[i].Copy());
            }
            r.current = current;
            return r;
        }
    }
}